/*
* This file is a part of the open-eBackup project.
* This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
* If a copy of the MPL was not distributed with this file, You can obtain one at
* http://mozilla.org/MPL/2.0/.
*
* Copyright (c) [2024] Huawei Technologies Co.,Ltd.
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
*/
#include "stub.h"
#include "gtest/gtest.h"
#include "gmock/gmock.h"
#include "gmock/gmock-actions.h"
#include "restore/HetroRestoreJob.h"
#include "utils/CertMgr.h"
#include "Backup.h"
#include "ScanMgr.h"
#include "constant/ErrorCodes.h"
#include "SmbContextArgs.h"
#include "device_access/dorado/DoradoBlock.h"

using namespace std;
using namespace PluginUtils;

namespace {
    constexpr auto MODULE = "HetroRestoreJob";
    constexpr uint32_t SCANNER_REPORT_CIRCLE_TIME = 60;  /* seconds */
    constexpr uint32_t DEFAULT_AGGREGATE_NUM = 32;
    constexpr uint32_t MAX_AGGREGATE_NUM = 1000;
    constexpr uint32_t DEFAULT_SMB_BLOCK_SIZE = 128 * 1024; // 128k
    constexpr auto FLRFILTERTYPE = "include";
    constexpr auto FLR_RESTORE_TYPE_ORIGIN_VALUE = "original";
    constexpr auto FLR_RESTORE_TYPE_NEW_VALUE = "newHomo";
    constexpr auto FLR_RESTORE_TYPE_NEW_VALUE2 = "new";
    constexpr auto FLR_RESTORE_TYPE_NATIVE_VALUE = "native";
    constexpr auto RESTORE_TYPE_HETER_NEW_VALUE = "newHeter";
    constexpr auto SPLIT_FIRST_PATH_LOCATION = 1;
    constexpr int MONITOR_SCAN_PROGRESS_INTERVAL = 10;
    constexpr int FIRST_GENERATE_CONTROL_FILE = 0;
    constexpr int MAX_OPEN_DIR_REQ_4000 = 4000;
}
class Scanner_test : public Scanner {
public:
    explicit Scanner_test(const ScanConfig& scanConfig);
    ~Scanner_test() {};

    SCANNER_STATUS Start() override;
    SCANNER_STATUS Abort()override;
    SCANNER_STATUS Destroy() override;
    SCANNER_STATUS Enqueue(const std::string& directory, const std::string& prefix = "", uint8_t filterFlag = 0) override;
    SCANNER_STATUS EnqueueV2(const std::string& directory) override;
    SCANNER_STATUS GetStatus() override;
    ScanStatistics GetStatistics() override;
    ErrRecorder QueryFailure() override;
    bool firstCall {true};

protected:
    ScanConfig m_config;
};

Scanner_test::Scanner_test(const ScanConfig& scanConfig) : Scanner(scanConfig) {}
SCANNER_STATUS Scanner_test::Start() {
    return SCANNER_STATUS::SUCCESS;
}
SCANNER_STATUS Scanner_test::Abort() {
    return SCANNER_STATUS::SUCCESS;
}
SCANNER_STATUS Scanner_test::Destroy() {
    return SCANNER_STATUS::SUCCESS;
}
SCANNER_STATUS Scanner_test::Enqueue(const std::string& directory, const std::string& prefix, uint8_t filterFlag) {
    return SCANNER_STATUS::SUCCESS;
}
SCANNER_STATUS Scanner_test::EnqueueV2(const std::string& directory) {
    return SCANNER_STATUS::SUCCESS;
}
SCANNER_STATUS Scanner_test::GetStatus() {
    if (firstCall) {
        firstCall = false;
        return SCANNER_STATUS::SCAN_IN_PROGRESS;
    }
    return SCANNER_STATUS::COMPLETED;
}
ScanStatistics Scanner_test::GetStatistics() {
    ScanStatistics scanStatistics;
    return scanStatistics;
}

ErrRecorder Scanner_test::QueryFailure() {
    ErrRecorder errRecorder {};
    return errRecorder;
}

namespace FS_Backup {
class testBackup : public Backup
{
public:
    explicit testBackup(const BackupParams& backupParams);
    testBackup(std::string source, std::string destination);
    ~testBackup() override;

    BackupRetCode Start() override;
    BackupRetCode Abort() override;
    BackupRetCode Destroy() override;
    BackupRetCode Enqueue(std::string contrlFile) override;
    BackupPhaseStatus GetStatus() override;
    BackupStats GetStats() override;
    std::unordered_set<FailedRecordItem, FailedRecordItemHash> GetFailedDetails() override;
};

testBackup::testBackup(const BackupParams& backupParams) :  Backup(backupParams) {};
testBackup::~testBackup() {};

BackupRetCode testBackup::Start()
{
    return BackupRetCode::SUCCESS;
}
BackupRetCode testBackup::Abort()
{
    return BackupRetCode::SUCCESS;
}
BackupRetCode testBackup::Destroy()
{
    return BackupRetCode::SUCCESS;
}
BackupRetCode testBackup::Enqueue(std::string contrlFile)
{
    return BackupRetCode::SUCCESS;
}
BackupPhaseStatus testBackup::GetStatus()
{
    return BackupPhaseStatus::COMPLETED;
}
BackupStats testBackup::GetStats()
{
    BackupStats backupStats;
    return backupStats;
}
std::unordered_set<FailedRecordItem, FailedRecordItemHash> testBackup::GetFailedDetails() {
    std::unordered_set<FailedRecordItem, FailedRecordItemHash> ret;
    return ret;
}
}

static void FunctionVoidSucc(void* obj) {
    return;
}

static bool FunctionBoolSucc(void* obj) {
    return true;
}

static void FillScanConfigBasedOnEnviroment_Stub(void *ob, ScanConfig &scanConfig)
{
    return;
}

static bool FunctionBoolFailed(void* obj) {
    return false;
}

static int FunctionIntSucc(void* obj) {
    return Module::SUCCESS;
}

static int  FunctionIntFailed(void* obj) {
    return Module::FAILED;
}

static char*  FunctionReturnString(void* obj) {
    char* str = "11111";
    return str;
}

static unique_ptr<Scanner> CreateScanInst_Stub (void* obj, ScanConfig scanConfig) {
    ScanConfig xx;
    return make_unique<Scanner_test>(xx);
}

static bool Initiate_Stub_Succ(void *obj, const ScanConfig &scanConfig)
{
    return true;
}

static SCANNER_STATUS StartScan_Stub_Succ(void* obj) {
    return SCANNER_STATUS::SUCCESS;
}

static SCANNER_STATUS AbortScan_Stub_Succ(void* obj) {
    return SCANNER_STATUS::SUCCESS;
}

static void Destroy_Stub(void* obj) {
    return;
}

static void Enqueue_Stub(void* obj, std::string directory, std::string prefix, uint8_t filterFlag) {
    return;
}

static SCANNER_STATUS GetScanStatus_Stub_Completed(void* obj) {
    return SCANNER_STATUS::COMPLETED;
}

static ScanStatistics GetScanStats_Stub(void* obj) {
    ScanStatistics scanStatistics;
    return scanStatistics;
}

static unique_ptr<FS_Backup::Backup> CreateBackupInstStub_Succ(void* obj, BackupParams backupParams) {
    BackupParams xx;
    return make_unique<FS_Backup::testBackup>(xx);
}

static int InitAggregateGenerateJobInfo_Succ()
{
    return Module::SUCCESS;
}

static bool UnzipDcachefiles_Stub_SUC()
{
    return true;
}

static bool g_firstCall = true;
static bool GetFileListInDirectoryStub_Succ(std::string dir, std::vector<string>& fileList)
{
    if (g_firstCall) {
        for (int i = 0; i <= 12 ; i++) {
            string controlFile = "File/mtime_" + to_string(i) +  ".txt";
            fileList.push_back(controlFile);
        }
        string controlFile1 = "File/hardlink_1.txt";
        string controlFile2 = "File/delete_1.txt";
        string controlFile3 = "File/control_1.txt";
        fileList.push_back(controlFile1);
        fileList.push_back(controlFile2);
        fileList.push_back(controlFile3);
        g_firstCall = false;
    }
    return true;
}

class HetroRestoreJobTest : public testing::Test {
public:
    void SetUp();
    void TearDown();
    static void SetUpTestCase();
    static void TearDownTestCase();

    AppProtect::RestoreJob RestoreJobInfoSetUp();
    AppProtect::RestoreJob RestoreJobInfoForAggregateSetUp();
    static void ReportProgressSucc();
    HetroRestoreJob m_ins;
    Stub m_stub;
    std::unique_ptr<HetroRestoreJob> m_nasHetroRestoreJob;
};

static void returnVoidStub(void* obj)
{
    return;
}

static bool StubOperateIpsRule(std::vector<std::string>& ipList, const std::string& operation)
{
    return true;
}

void HetroRestoreJobTest::SetUp()
{
    m_stub.set(ADDR(PluginUtils, OperateIpsRule), StubOperateIpsRule);
    m_stub.set(sleep, returnVoidStub);
    m_stub.set(ADDR(HetroRestoreJob, FillScanConfigBasedOnEnviroment), FillScanConfigBasedOnEnviroment_Stub);
    m_stub.set(ADDR(JobService, ReportJobDetails), HetroRestoreJobTest::ReportProgressSucc);
    m_stub.set(ADDR(SecurityService, CheckCertThumbPrint), FunctionVoidSucc);
    m_stub.set(ADDR(HetroCommonService, ReadBackupCopyFromFile), FunctionBoolSucc);
    m_stub.set(PluginUtils::CheckNfsAccessibility, FunctionIntSucc);
    m_stub.set(PluginUtils::MountNFS, FunctionIntSucc);
    m_stub.set(PluginUtils::UnmountNas, FunctionIntSucc);
    m_stub.set(ADDR(Module::SmbContextWrapper, SmbConnect), FunctionBoolSucc);
    m_stub.set(ADDR(Module::SmbContextWrapper, SmbGetMaxReadSize), FunctionIntSucc);
    m_stub.set(ADDR(Module::SmbContextWrapper, SmbGetMaxWriteSize), FunctionIntSucc);
    m_stub.set(ADDR(Module::SmbContextWrapper, SmbGetClientGuid), FunctionReturnString);
    m_stub.set(smb2_destroy_context, FunctionVoidSucc);
    m_stub.set(ADDR(ShareResource, CreateResource), FunctionVoidSucc);
    m_stub.set(ADDR(ShareResource, QueryResource), FunctionVoidSucc);
    m_stub.set(ADDR(ShareResource, UpdateResource), FunctionVoidSucc);
    m_stub.set(ADDR(ShareResource, DeleteResource), FunctionVoidSucc);
    m_stub.set(ADDR(ShareResource, LockResource), FunctionVoidSucc);
    m_stub.set(ADDR(ShareResource, UnLockResource), FunctionVoidSucc);
    m_stub.set(sleep, FunctionVoidSucc);
    m_stub.set(ADDR(HetroCommonService, GetGeneralResource), FunctionBoolSucc);
    m_stub.set(ADDR(HetroCommonService, GetScanStatsResource), FunctionBoolSucc);
    m_stub.set(ADDR(HetroCommonService, GetBackupStatsResource), FunctionBoolSucc);
    m_stub.set(ADDR(CertMgr, InitInfo), FunctionBoolSucc);
    m_stub.set(ADDR(CertMgr, IsVerify), FunctionBoolSucc);
    m_stub.set(ADDR(CertMgr, IncludeRevocationList), FunctionBoolSucc);
    m_stub.set(ADDR(CertMgr, FlushCertificationToDisk), FunctionBoolSucc);
    m_stub.set(ADDR(CertMgr, FlushRevocationListToDisk), FunctionBoolSucc);
    m_stub.set(ADDR(CertMgr, RemoveCertAndRevocationListFromDisk), FunctionBoolSucc);
}

void HetroRestoreJobTest::TearDown()
{
    m_stub.reset(ADDR(JobService, ReportJobDetails));
    m_stub.reset(ADDR(HetroRestoreJob, FillScanConfigBasedOnEnviroment));
    m_stub.reset(ADDR(SecurityService, CheckCertThumbPrint));
    m_stub.reset(ADDR(HetroCommonService, ReadBackupCopyFromFile));
    m_stub.reset(PluginUtils::MountNFS);
    m_stub.reset(PluginUtils::UnmountNas);
    m_stub.reset(ADDR(Module::SmbContextWrapper, SmbConnect));
    m_stub.reset(ADDR(Module::SmbContextWrapper, SmbGetMaxReadSize));
    m_stub.reset(ADDR(Module::SmbContextWrapper, SmbGetMaxWriteSize));
    m_stub.reset(ADDR(Module::SmbContextWrapper, SmbGetClientGuid));
    m_stub.reset(smb2_destroy_context);
    m_stub.reset(ADDR(ShareResource, CreateResource));
    m_stub.reset(ADDR(ShareResource, QueryResource));
    m_stub.reset(ADDR(ShareResource, UpdateResource));
    m_stub.reset(ADDR(ShareResource, DeleteResource));
    m_stub.reset(ADDR(ShareResource, LockResource));
    m_stub.reset(ADDR(ShareResource, UnLockResource));
    m_stub.reset(sleep);
    m_stub.reset(ADDR(HetroCommonService, GetGeneralResource));
    m_stub.reset(ADDR(HetroCommonService, GetScanStatsResource));
    m_stub.reset(ADDR(HetroCommonService, GetBackupStatsResource));
    m_stub.reset(ADDR(CertMgr, InitInfo));
    m_stub.reset(ADDR(CertMgr, IsVerify));
    m_stub.reset(ADDR(CertMgr, IncludeRevocationList));
    m_stub.reset(ADDR(CertMgr, FlushCertificationToDisk));
    m_stub.reset(ADDR(CertMgr, FlushRevocationListToDisk));
    m_stub.reset(ADDR(CertMgr, RemoveCertAndRevocationListFromDisk));
}

void HetroRestoreJobTest::SetUpTestCase()
{
    // std::cout << "Enter HetroRestoreJobTest::SetUpTestCase" <<std::endl;
}

void HetroRestoreJobTest::TearDownTestCase()
{
    // std::cout << "Exit HetroRestoreJobTest::TearDownTestCase" <<std::endl; 
}

void HetroRestoreJobTest::ReportProgressSucc() {
    return;
}

AppProtect::RestoreJob HetroRestoreJobTest::RestoreJobInfoSetUp()
{
    AppProtect::RestoreJob restoreJob;
    restoreJob.requestId = "123456789";
    restoreJob.jobId = "111111";
    restoreJob.targetEnv.subType = "1";
    restoreJob.targetObject.id = "123";
    restoreJob.targetObject.name = "123";
    restoreJob.targetEnv.endpoint = "10.28.12.144";
    restoreJob.targetObject.subType ="5";

    string extendInfoStr;

    HetroApplicationNasExtent hetroApplicationNasExtent;
    hetroApplicationNasExtent.m_serviceIP = "10.10.10.10";
    hetroApplicationNasExtent.m_protocol = "1";
    hetroApplicationNasExtent.m_authMode = "1";
    hetroApplicationNasExtent.m_kerberosId = "11111";
    hetroApplicationNasExtent.m_filters = "qqqqqq";
    hetroApplicationNasExtent.m_username = "root";
    hetroApplicationNasExtent.m_password = "admin@123";
    hetroApplicationNasExtent.m_encryption = "2";
    hetroApplicationNasExtent.m_domainName = "aaaaaaaaa";
    hetroApplicationNasExtent.m_isAutoScan = "1";
    Module::JsonHelper::StructToJsonString(hetroApplicationNasExtent, extendInfoStr);
    restoreJob.targetObject.extendInfo = extendInfoStr;

    EnvAuthExtendInfo authExtendInfo {};
    authExtendInfo.m_fingerPrint = "11111";
    Module::JsonHelper::StructToJsonString(authExtendInfo, extendInfoStr);
    restoreJob.targetEnv.auth.extendInfo = extendInfoStr;

    ApplicationEnvExtent applicationEnvExtentInfo {};
    applicationEnvExtentInfo.m_verifyStatus = "1";
    Module::JsonHelper::StructToJsonString(applicationEnvExtentInfo, extendInfoStr);
    restoreJob.targetEnv.extendInfo = extendInfoStr;

    HostAddress hostaddress;
    hostaddress.ip="10.28.12.144";
    hostaddress.port = 0;
    hostaddress.supportProtocol = 3;

    string path = "/MetaFS/cache";
    StorageRepository cacheRepo;
    cacheRepo.repositoryType = RepositoryDataType::CACHE_REPOSITORY;
    cacheRepo.path.push_back(path);
    cacheRepo.remoteHost.push_back(hostaddress);
    cacheRepo.endpoint.ip = "10.10.11.10";
    cacheRepo.auth.authkey = "111";
    cacheRepo.auth.authPwd = "111";

    StorageRepository dataRepo;
    dataRepo.repositoryType = RepositoryDataType::DATA_REPOSITORY;
    dataRepo.path.push_back(dataRepo.remotePath);
    dataRepo.remoteHost.push_back(hostaddress);
    dataRepo.auth.authkey = "111";
    dataRepo.endpoint.ip = "10.10.11.10";
    dataRepo.auth.authPwd = "111";

    StorageRepository metaRepo;
    metaRepo.repositoryType = RepositoryDataType::META_REPOSITORY;
    metaRepo.path.push_back(path);
    metaRepo.remoteHost.push_back(hostaddress);
    metaRepo.endpoint.ip = "10.10.11.10";
    metaRepo.auth.authkey = "111";
    metaRepo.auth.authPwd = "111";

    Copy copy;      
    copy.repositories.push_back(cacheRepo);
    copy.repositories.push_back(dataRepo);
    copy.repositories.push_back(metaRepo);

    AggCopyExtendInfo aggCopyExtendInfo;
    aggCopyExtendInfo.dataPathSuffix = "test6666666";
    aggCopyExtendInfo.dataPathSuffix = "test8888888";
    aggCopyExtendInfo.maxSizeToAggregate = "222222222";
    aggCopyExtendInfo.maxSizeAfterAggregate = "22222222";
    string aggCopyExtendInfoStr;
    Module::JsonHelper::StructToJsonString(aggCopyExtendInfo, aggCopyExtendInfoStr);
    copy.extendInfo = aggCopyExtendInfoStr;
    copy.protectObject.subType = "NasShare";
    restoreJob.copies.push_back(copy);
    restoreJob.copies.push_back(copy);

    FlrRestoreExtend flrRestoreExtend;
    flrRestoreExtend.fileReplaceStrategy = "0";
    flrRestoreExtend.shareIp = "192.168.129.173";
    flrRestoreExtend.authType = "0";
    flrRestoreExtend.protocol = "1"; // 1 代表nfs
    flrRestoreExtend.sharePath = "/File_1GB_0002/";
    flrRestoreExtend.targetLocation = "newHomo";
    flrRestoreExtend.targetPath = "/";
    Module::JsonHelper::StructToJsonString(flrRestoreExtend, extendInfoStr);
    restoreJob.extendInfo = extendInfoStr;

    std::vector<ApplicationResource>  restoreSubObjects;
    ApplicationResource applicationResource;
    applicationResource.name = "/1.txt";
    restoreJob.restoreSubObjects.push_back(applicationResource);
    applicationResource.name = "/A_dir/";
    restoreJob.restoreSubObjects.push_back(applicationResource);

    ResourceFilter resourceFilter;
    restoreJob.jobParam.filters.push_back(resourceFilter);
    restoreJob.jobParam.restoreType = RestoreJobType::NORMAL_RESTORE;

    return restoreJob;
}

TEST_F(HetroRestoreJobTest, PrerequisiteJob)
{
    Stub stub;
    std::shared_ptr<ThriftDataBase> restoreJobInfoPtr =
        std::make_shared<AppProtect::RestoreJob>(HetroRestoreJobTest::RestoreJobInfoSetUp());
    m_ins.m_jobCommonInfo = std::make_shared<JobCommonInfo>(restoreJobInfoPtr);

    int ret = m_ins.PrerequisiteJob();
    EXPECT_EQ(ret, Module::SUCCESS);

    stub.set(ADDR(HetroRestoreJob, PrerequisiteJobInner), FunctionIntFailed);
    ret = m_ins.PrerequisiteJob();
    EXPECT_EQ(ret, Module::FAILED);

    stub.reset(ADDR(HetroRestoreJob, PrerequisiteJobInner));
}

/*
 * 用例名称:检查走扫描的分解任务流程
 * 前置条件：无
 * check点：检查分解任务流程顺利运行
 */
TEST_F(HetroRestoreJobTest, GenerateSubJobInnerForFileSystem)
{
    AppProtect::RestoreJob jobInfo = HetroRestoreJobTest::RestoreJobInfoSetUp();
    jobInfo.copies[0].protectObject.subType = "NasFileSystem";
    jobInfo.targetObject.subType = "NasShare";
    std::shared_ptr<ThriftDataBase> restoreJobInfoPtr =
        std::make_shared<AppProtect::RestoreJob>(jobInfo);
    m_ins.m_jobCommonInfo = std::make_shared<JobCommonInfo>(restoreJobInfoPtr);
    g_firstCall = true;
    Stub stub;
    stub.set(ADDR(ScanMgr, CreateScanInst), CreateScanInst_Stub);
    stub.set(PluginUtils::CreateDirectory, FunctionBoolSucc);
    stub.set(PluginUtils::RemoveFile, FunctionBoolSucc);
    stub.set(PluginUtils::CopyFile, FunctionBoolSucc);
    stub.set(Module::runShellCmdWithOutput, FunctionIntSucc);
    stub.set(PluginUtils::GetFileListInDirectory, GetFileListInDirectoryStub_Succ);
    stub.set(ADDR(JobService, AddNewJob), FunctionVoidSucc);
    stub.set(PluginUtils::PathExistMandate, FunctionBoolSucc);
    stub.set(ADDR(HetroCommonService, GetGeneralResource), FunctionBoolSucc);
    stub.set(ADDR(HetroCommonService, GetScanStatsResource), FunctionBoolSucc);
    stub.set(ADDR(HetroCommonService, GetBackupStatsResource), FunctionBoolSucc);

    int ret = m_ins.GenerateSubJob();
    EXPECT_EQ(ret, Module::SUCCESS);

    stub.reset(ADDR(ScanMgr, CreateScanInst));
    stub.reset(PluginUtils::CreateDirectory);
    stub.reset(PluginUtils::RemoveFile);
    stub.reset(PluginUtils::CopyFile);
    stub.reset(Module::runShellCmdWithOutput);
    stub.reset(PluginUtils::GetFileListInDirectory);
    stub.reset(ADDR(JobService, AddNewJob));
    stub.reset(PluginUtils::PathExistMandate);
    stub.reset(ADDR(HetroCommonService, GetGeneralResource));
    stub.reset(ADDR(HetroCommonService, GetScanStatsResource));
    stub.reset(ADDR(HetroCommonService, GetBackupStatsResource));
}

/*
 * 用例名称:检查走聚合的分解任务流程
 * 前置条件：无
 * check点：检查分解任务流程顺利运行
 */
TEST_F(HetroRestoreJobTest, GenerateAggregateSubJobInner)
{
    AppProtect::RestoreJob jobInfo = HetroRestoreJobTest::RestoreJobInfoSetUp();
    jobInfo.copies[0].formatType = CopyFormatType::type::INNER_DIRECTORY;
    std::shared_ptr<ThriftDataBase> restoreJobInfoPtr =
        std::make_shared<AppProtect::RestoreJob>(jobInfo);
    m_ins.m_jobCommonInfo = std::make_shared<JobCommonInfo>(restoreJobInfoPtr);
    g_firstCall = true;
    Stub stub;
    stub.set(ADDR(ScanMgr, Initiate), Initiate_Stub_Succ);
    stub.set(ADDR(ScanMgr, StartScan), StartScan_Stub_Succ);
    stub.set(ADDR(ScanMgr, AbortScan), AbortScan_Stub_Succ);
    stub.set(ADDR(ScanMgr, Destroy), Destroy_Stub);
    stub.set(ADDR(ScanMgr, Enqueue), Enqueue_Stub);
    stub.set(ADDR(ScanMgr, GetScanStatus), GetScanStatus_Stub_Completed);
    stub.set(ADDR(ScanMgr, GetScanStats), GetScanStats_Stub);
    stub.set(PluginUtils::CreateDirectory, FunctionBoolSucc);
    stub.set(PluginUtils::RemoveFile, FunctionBoolSucc);
    stub.set(PluginUtils::CopyFile, FunctionBoolSucc);
    stub.set(Module::runShellCmdWithOutput, FunctionIntSucc);
    stub.set(PluginUtils::GetFileListInDirectory, GetFileListInDirectoryStub_Succ);
    stub.set(ADDR(JobService, AddNewJob), FunctionVoidSucc);
    stub.set(PluginUtils::PathExistMandate, FunctionBoolSucc);
    stub.set(ADDR(HetroCommonService, GetGeneralResource), FunctionBoolSucc);
    stub.set(ADDR(HetroCommonService, GetScanStatsResource), FunctionBoolSucc);
    stub.set(ADDR(HetroCommonService, GetBackupStatsResource), FunctionBoolSucc);
    stub.set(ADDR(HetroRestoreJob, InitAggregateGenerateJobInfo), InitAggregateGenerateJobInfo_Succ);

    int ret = m_ins.GenerateSubJob();
    EXPECT_EQ(ret, Module::SUCCESS);

    stub.reset(ADDR(ScanMgr, Initiate));
    stub.reset(ADDR(ScanMgr, StartScan));
    stub.reset(ADDR(ScanMgr, AbortScan));
    stub.reset(ADDR(ScanMgr, Destroy));
    stub.reset(ADDR(ScanMgr, Enqueue));
    stub.reset(ADDR(ScanMgr, GetScanStatus));
    stub.reset(ADDR(ScanMgr, GetScanStats));
    stub.reset(PluginUtils::CreateDirectory);
    stub.reset(PluginUtils::RemoveFile);
    stub.reset(PluginUtils::CopyFile);
    stub.reset(Module::runShellCmdWithOutput);
    stub.reset(PluginUtils::GetFileListInDirectory);
    stub.reset(ADDR(JobService, AddNewJob));
    stub.reset(PluginUtils::PathExistMandate);
    stub.reset(ADDR(HetroCommonService, GetGeneralResource));
    stub.reset(ADDR(HetroCommonService, GetScanStatsResource));
    stub.reset(ADDR(HetroCommonService, GetBackupStatsResource));
    stub.reset(ADDR(HetroRestoreJob, InitAggregateGenerateJobInfo));
}

/*
 * 用例名称:检查走dcache、fcache的分解任务流程
 * 前置条件：无
 * check点：检查分解任务流程顺利运行
 */
TEST_F(HetroRestoreJobTest, GenerateSubJobInner)
{
    AppProtect::RestoreJob jobInfo = HetroRestoreJobTest::RestoreJobInfoSetUp();
    jobInfo.copies[0].formatType = CopyFormatType::type::INNER_SNAPSHOT;
    jobInfo.jobParam.restoreType = RestoreJobType::FINE_GRAINED_RESTORE;
    std::shared_ptr<ThriftDataBase> restoreJobInfoPtr =
        std::make_shared<AppProtect::RestoreJob>(jobInfo);
    m_ins.m_jobCommonInfo = std::make_shared<JobCommonInfo>(restoreJobInfoPtr);
    g_firstCall = true;
    Stub stub;
    stub.set(ADDR(ScanMgr, Initiate), Initiate_Stub_Succ);
    stub.set(ADDR(ScanMgr, StartScan), StartScan_Stub_Succ);
    stub.set(ADDR(ScanMgr, AbortScan), AbortScan_Stub_Succ);
    stub.set(ADDR(ScanMgr, Destroy), Destroy_Stub);
    stub.set(ADDR(ScanMgr, Enqueue), Enqueue_Stub);
    stub.set(ADDR(ScanMgr, GetScanStatus), GetScanStatus_Stub_Completed);
    stub.set(ADDR(ScanMgr, GetScanStats), GetScanStats_Stub);
    stub.set(PluginUtils::CreateDirectory, FunctionBoolSucc);
    stub.set(PluginUtils::RemoveFile, FunctionBoolSucc);
    stub.set(PluginUtils::CopyFile, FunctionBoolSucc);
    stub.set(Module::runShellCmdWithOutput, FunctionIntSucc);
    stub.set(PluginUtils::GetFileListInDirectory, GetFileListInDirectoryStub_Succ);
    stub.set(ADDR(JobService, AddNewJob), FunctionVoidSucc);
    stub.set(PluginUtils::PathExistMandate, FunctionBoolSucc);
    stub.set(ADDR(HetroCommonService, GetGeneralResource), FunctionBoolSucc);
    stub.set(ADDR(HetroCommonService, GetScanStatsResource), FunctionBoolSucc);
    stub.set(ADDR(HetroCommonService, GetBackupStatsResource), FunctionBoolSucc);
    stub.set(ADDR(HetroRestoreJob, UnzipDcachefiles), UnzipDcachefiles_Stub_SUC);

    int ret = m_ins.GenerateSubJob();
    EXPECT_EQ(ret, Module::SUCCESS);

    stub.reset(ADDR(ScanMgr, Initiate));
    stub.reset(ADDR(ScanMgr, StartScan));
    stub.reset(ADDR(ScanMgr, AbortScan));
    stub.reset(ADDR(ScanMgr, Destroy));
    stub.reset(ADDR(ScanMgr, Enqueue));
    stub.reset(ADDR(ScanMgr, GetScanStatus));
    stub.reset(ADDR(ScanMgr, GetScanStats));
    stub.reset(PluginUtils::CreateDirectory);
    stub.reset(PluginUtils::RemoveFile);
    stub.reset(PluginUtils::CopyFile);
    stub.reset(Module::runShellCmdWithOutput);
    stub.reset(PluginUtils::GetFileListInDirectory);
    stub.reset(ADDR(JobService, AddNewJob));
    stub.reset(PluginUtils::PathExistMandate);
    stub.reset(ADDR(HetroCommonService, GetGeneralResource));
    stub.reset(ADDR(HetroCommonService, GetScanStatsResource));
    stub.reset(ADDR(HetroCommonService, GetBackupStatsResource));
    stub.reset(ADDR(HetroRestoreJob, UnzipDcachefiles));
}

/*
 * 用例名称:检查NFS执行子任务流程
 * 前置条件：无
 * check点：检查执行子任务流程顺利运行
 */
TEST_F(HetroRestoreJobTest, ExecuteSubJob_NFS)
{
    Stub stub;
    stub.set(ADDR(FS_Backup::BackupMgr, CreateBackupInst), CreateBackupInstStub_Succ);

    std::shared_ptr<ThriftDataBase> restoreJobInfoPtr =
        std::make_shared<AppProtect::RestoreJob>(HetroRestoreJobTest::RestoreJobInfoSetUp());
    m_ins.m_jobCommonInfo = std::make_shared<JobCommonInfo>(restoreJobInfoPtr);

    HetroBackupSubJob subJobInfo;
    subJobInfo.dataCachePath = "/home";
    subJobInfo.metaFilePath = "/home";
    subJobInfo.dcacheAndFcachePath = "/home";
    subJobInfo.copyId = "111111111111";
    subJobInfo.m_ControlFile = "test_control.txt";
    string subJobInfoStr;
    SubJob subJob;

    subJobInfo.m_SubTaskType = SUBJOB_TYPE_DATACOPY_COPY_PHASE;
    Module::JsonHelper::StructToJsonString(subJobInfo, subJobInfoStr);
    subJob.jobInfo = subJobInfoStr;
    m_ins.SetSubJob(std::make_shared<SubJob>(subJob));
    int ret = m_ins.ExecuteSubJob();
    EXPECT_EQ(ret, Module::SUCCESS);

    subJobInfo.m_SubTaskType = SUBJOB_TYPE_DATACOPY_DELETE_PHASE;
    Module::JsonHelper::StructToJsonString(subJobInfo, subJobInfoStr);
    subJob.jobInfo = subJobInfoStr;
    m_ins.SetSubJob(std::make_shared<SubJob>(subJob));
    ret = m_ins.ExecuteSubJob();
    EXPECT_EQ(ret, Module::SUCCESS);

    subJobInfo.m_SubTaskType = SUBJOB_TYPE_DATACOPY_HARDLINK_PHASE;
    Module::JsonHelper::StructToJsonString(subJobInfo, subJobInfoStr);
    subJob.jobInfo = subJobInfoStr;
    m_ins.SetSubJob(std::make_shared<SubJob>(subJob));
    ret = m_ins.ExecuteSubJob();
    EXPECT_EQ(ret, Module::SUCCESS);

    subJobInfo.m_SubTaskType = SUBJOB_TYPE_DATACOPY_DIRMTIME_PHASE;
    Module::JsonHelper::StructToJsonString(subJobInfo, subJobInfoStr);
    subJob.jobInfo = subJobInfoStr;
    m_ins.SetSubJob(std::make_shared<SubJob>(subJob));
    ret = m_ins.ExecuteSubJob();
    EXPECT_EQ(ret, Module::SUCCESS);

    stub.reset(ADDR(FS_Backup::BackupMgr, CreateBackupInst));
}

/*
 * 用例名称:检查CIFS执行子任务流程
 * 前置条件：无
 * check点：检查执行子任务流程顺利运行
 */
TEST_F(HetroRestoreJobTest, ExecuteSubJob_CIFS)
{
    AppProtect::RestoreJob jobInfo = HetroRestoreJobTest::RestoreJobInfoSetUp();

    string extendInfoStr;
    FlrRestoreExtend flrRestoreExtend;
    flrRestoreExtend.authType = "0";
    flrRestoreExtend.fileReplaceStrategy = "0";
    flrRestoreExtend.shareIp = "192.168.129.173";
    flrRestoreExtend.targetLocation = "newHomo";
    flrRestoreExtend.protocol = "0";   // 0 代表CIFS
    flrRestoreExtend.sharePath = "/File_1GB_0002/";
    flrRestoreExtend.targetPath = "/";
    Module::JsonHelper::StructToJsonString(flrRestoreExtend, extendInfoStr);
    jobInfo.extendInfo = extendInfoStr;

    std::shared_ptr<ThriftDataBase> restoreJobInfoPtr =
        std::make_shared<AppProtect::RestoreJob>(jobInfo);
    m_ins.m_jobCommonInfo = std::make_shared<JobCommonInfo>(restoreJobInfoPtr);

    HetroBackupSubJob subJobInfo;
    subJobInfo.dataCachePath = "/home";
    subJobInfo.metaFilePath = "/home";
    subJobInfo.dcacheAndFcachePath = "/home";
    subJobInfo.copyId = "111111111111";
    subJobInfo.m_ControlFile = "test_control.txt";
    subJobInfo.m_SubTaskType = SUBJOB_TYPE_DATACOPY_COPY_PHASE;
    string subJobInfoStr;
    Module::JsonHelper::StructToJsonString(subJobInfo, subJobInfoStr);
    SubJob subJob;
    subJob.jobInfo = subJobInfoStr;
    m_ins.SetSubJob(std::make_shared<SubJob>(subJob));

    Stub stub;
    stub.set(ADDR(FS_Backup::BackupMgr, CreateBackupInst), CreateBackupInstStub_Succ);

    int ret = m_ins.ExecuteSubJob();
    EXPECT_EQ(ret, Module::SUCCESS);
    stub.reset(ADDR(FS_Backup::BackupMgr, CreateBackupInst));
}


/*
 * 用例名称:检查后置任务流程
 * 前置条件：无
 * check点：检查后置任务流程顺利运行
 */
TEST_F(HetroRestoreJobTest, PostJob)
{
    std::shared_ptr<ThriftDataBase> restoreJobInfoPtr =
        std::make_shared<AppProtect::RestoreJob>(HetroRestoreJobTest::RestoreJobInfoSetUp());
    m_ins.m_jobCommonInfo = std::make_shared<JobCommonInfo>(restoreJobInfoPtr);

    Stub stub;
    stub.set( PluginUtils::Remove, FunctionBoolSucc);
    int ret = m_ins.PostJob();
    EXPECT_EQ(ret, Module::SUCCESS);

    stub.set( PluginUtils::Remove, FunctionBoolFailed);
    ret = m_ins.PostJob();
    EXPECT_EQ(ret, Module::SUCCESS);

    stub.reset( PluginUtils::Remove);
}

std::shared_ptr<JobCommonInfo> ReturnNullptr() {
    return nullptr;
}

/*
 * 用例名称:增加前置任务的行覆盖率
 * 前置条件：无
 * check点：仅仅增加行覆盖率
 */
TEST_F(HetroRestoreJobTest, PreAddBranchCoverage)
{
    Stub stub;
    AppProtect::RestoreJob jobInfo = HetroRestoreJobTest::RestoreJobInfoSetUp();
    std::shared_ptr<ThriftDataBase> restoreJobInfoPtr =
        std::make_shared<AppProtect::RestoreJob>(jobInfo);
    m_ins.m_jobCommonInfo = std::make_shared<JobCommonInfo>(restoreJobInfoPtr);

    stub.set(ADDR(JobCommonInfo, GetJobInfo), ReturnNullptr);
    int ret = m_ins.GetRestoreJobInfo();
    EXPECT_EQ(ret, false);
    stub.reset(ADDR(JobCommonInfo, GetJobInfo));

    stub.set(ADDR(HetroRestoreJob, GetRestoreJobInfo), FunctionBoolFailed);
    ret = m_ins.PrerequisiteJob();
    EXPECT_EQ(ret, Module::FAILED);
    ret = m_ins.GenerateSubJob();
    EXPECT_EQ(ret, Module::FAILED);
    ret = m_ins.ExecuteSubJob();
    EXPECT_EQ(ret, Module::FAILED);
    ret = m_ins.PostJob();
    EXPECT_EQ(ret, Module::FAILED);
    stub.reset(ADDR(HetroRestoreJob, GetRestoreJobInfo));

    // SubJob subJob;
    // subJob.jobInfo = "xxxxxxxxx";
    // m_ins.SetSubJob(std::make_shared<SubJob>(subJob));
    // ret = m_ins.ExecuteSubJob();
    // EXPECT_EQ(ret, Module::FAILED);

    // HetroBackupSubJob subJobInfo;
    // subJobInfo.dataCachePath = "/home";
    // subJobInfo.metaFilePath = "/home";
    // subJobInfo.dcacheAndFcachePath = "/home";
    // subJobInfo.copyId = "111111111111";
    // subJobInfo.m_ControlFile = "test_control.txt";
    // subJobInfo.m_SubTaskType = SUBJOB_TYPE_DATACOPY_COPY_PHASE;
    // string subJobInfoStr;
    // Module::JsonHelper::StructToJsonString(subJobInfo, subJobInfoStr);
    // subJob.jobInfo = subJobInfoStr;
    // m_ins.SetSubJob(std::make_shared<SubJob>(subJob));
    // stub.set(ADDR(HetroRestoreJob, callCheckCertThumbPrint), FunctionIntFailed);
    // ret = m_ins.PrerequisiteJob();
    // EXPECT_EQ(ret, Module::FAILED);
    // stub.reset(ADDR(HetroRestoreJob, callCheckCertThumbPrint));

    // stub.set(ADDR(HetroRestoreJob, InitJobInfo), FunctionBoolFailed);
    // ret = m_ins.PrerequisiteJob();
    // EXPECT_EQ(ret, Module::FAILED);
    // stub.reset(ADDR(HetroRestoreJob, InitJobInfo));

    // stub.set(ADDR(HetroRestoreJob, CheckNasSharesReachable), FunctionBoolFailed);
    // ret = m_ins.PrerequisiteJob();
    // EXPECT_EQ(ret, Module::FAILED);
    // stub.reset(ADDR(HetroRestoreJob, CheckNasSharesReachable));

    // stub.set(ADDR(HetroRestoreJob, CreateSharedResources), FunctionBoolFailed);
    // ret = m_ins.PrerequisiteJob();
    // EXPECT_EQ(ret, Module::FAILED);
    // stub.reset(ADDR(HetroRestoreJob, CreateSharedResources));

    // stub.set(ADDR(HetroRestoreJob, SetupMetaFsForRestoreJob), FunctionBoolFailed);
    // ret = m_ins.PrerequisiteJob();
    // EXPECT_EQ(ret, Module::FAILED);
    // stub.reset(ADDR(HetroRestoreJob, SetupMetaFsForRestoreJob));

    // stub.set(ADDR(HetroRestoreJob, UpdateGeneralResource), FunctionBoolFailed);
    // ret = m_ins.PrerequisiteJob();
    // EXPECT_EQ(ret, Module::FAILED);
    // stub.reset(ADDR(HetroRestoreJob, UpdateGeneralResource));

    // jobInfo = HetroRestoreJobTest::RestoreJobInfoSetUp();
    // jobInfo.targetEnv.auth.extendInfo = "";
    // restoreJobInfoPtr = std::make_shared<AppProtect::RestoreJob>(jobInfo);
    // m_ins.m_jobCommonInfo = std::make_shared<JobCommonInfo>(restoreJobInfoPtr);
    // ret = m_ins.PrerequisiteJob();
    // EXPECT_EQ(ret, Module::FAILED);

    // subJob.jobInfo = "";
    // m_ins.SetSubJob(std::make_shared<SubJob>(subJob));
    // ret = m_ins.PrerequisiteJob();
    // EXPECT_EQ(ret, Module::FAILED);
    // stub.reset(ADDR(HetroRestoreJob, callCheckCertThumbPrint));
}

/*
 * 用例名称：CheckFillMonitorScannerVarDetails
 * 前置条件：无
 * check点：FillMonitorScannerVarDetails根据m_scanStatus不同进入不同分支
 */
TEST_F(HetroRestoreJobTest, CheckFillMonitorScannerVarDetails)
{
    // auto obj_index = std::make_unique<HetroRestoreJobTest>();
    m_nasHetroRestoreJob = std::make_unique<HetroRestoreJob>();
    SCANNER_TASK_STATUS scanTaskStatus =
        SCANNER_TASK_STATUS::SCANNER_TASK_STATUS_SUCCESS;
    SubJobStatus::type jobStatus = SubJobStatus::COMPLETED;
    std::string jobLogLabel = "nas_plugin_hetro_backup_scan_completed_label";
    constexpr uint32_t PROGRESS100 = 100;
    int jobProgress = PROGRESS100;
    m_nasHetroRestoreJob->m_scanStatus = SCANNER_STATUS::FAILED;
    m_nasHetroRestoreJob->FillMonitorScannerVarDetails(scanTaskStatus, jobStatus, jobLogLabel, jobProgress);
    EXPECT_EQ(jobStatus, SubJobStatus::FAILED);

    m_nasHetroRestoreJob->m_scanStatus = SCANNER_STATUS::ABORT_IN_PROGRESS;
    m_nasHetroRestoreJob->FillMonitorScannerVarDetails(scanTaskStatus, jobStatus, jobLogLabel, jobProgress);
    EXPECT_EQ(jobStatus, SubJobStatus::ABORTING);

    m_nasHetroRestoreJob->m_scanStatus = SCANNER_STATUS::ABORTED;
    m_nasHetroRestoreJob->FillMonitorScannerVarDetails(scanTaskStatus, jobStatus, jobLogLabel, jobProgress);
    EXPECT_EQ(jobStatus, SubJobStatus::ABORTED);

    m_nasHetroRestoreJob->m_scanStatus = SCANNER_STATUS::SCAN_READ_COMPLETED;
    m_nasHetroRestoreJob->FillMonitorScannerVarDetails(scanTaskStatus, jobStatus, jobLogLabel, jobProgress);
    EXPECT_EQ(jobStatus, SubJobStatus::RUNNING);

    m_nasHetroRestoreJob->m_scanStatus = SCANNER_STATUS::CTRL_DIFF_IN_PROGRESS;
    m_nasHetroRestoreJob->FillMonitorScannerVarDetails(scanTaskStatus, jobStatus, jobLogLabel, jobProgress);
    EXPECT_EQ(jobStatus, SubJobStatus::RUNNING);

    m_nasHetroRestoreJob->m_scanStatus = SCANNER_STATUS::SECONDARY_SERVER_NOT_REACHABLE;
    m_nasHetroRestoreJob->FillMonitorScannerVarDetails(scanTaskStatus, jobStatus, jobLogLabel, jobProgress);
    EXPECT_EQ(jobStatus, SubJobStatus::FAILED);

    m_nasHetroRestoreJob->m_scanStatus = SCANNER_STATUS::PROTECTED_SERVER_NOT_REACHABLE;
    m_nasHetroRestoreJob->FillMonitorScannerVarDetails(scanTaskStatus, jobStatus, jobLogLabel, jobProgress);
    EXPECT_EQ(jobStatus, SubJobStatus::FAILED);

    m_nasHetroRestoreJob->m_scanStatus = SCANNER_STATUS::ERROR_INC_TO_FULL;
    m_nasHetroRestoreJob->FillMonitorScannerVarDetails(scanTaskStatus, jobStatus, jobLogLabel, jobProgress);
    EXPECT_EQ(jobStatus, SubJobStatus::FAILED);
}

// TEST_F(HetroRestoreJobTest, CheckFillBackupCIFSConfig)
// {
//     std::shared_ptr<ThriftDataBase> restoreJobInfoPtr =
//         std::make_shared<AppProtect::RestoreJob>(HetroRestoreJobTest::RestoreJobInfoSetUp());
//     m_ins.m_jobCommonInfo = std::make_shared<JobCommonInfo>(restoreJobInfoPtr);
//     BackupParams backupParams;
//     EXPECT_NO_THROW(m_ins.FillBackupCIFSConfig(backupParams));
// }

/*
 * 用例名称：CheckFillBackupConfigPhase
 * 前置条件：无
 * check点：FillBackupConfigPhase进入不同分支
 */
TEST_F(HetroRestoreJobTest, CheckFillBackupConfigPhase)
{
    HetroBackupSubJob backupSubJob;
    BackupParams backupParams;

    backupSubJob.m_SubTaskType = SUBJOB_TYPE_DATACOPY_COPY_PHASE;
    backupParams.phase = BackupPhase::COPY_STAGE;
    m_nasHetroRestoreJob->FillBackupConfigPhase(backupParams, backupSubJob);
    EXPECT_EQ(backupParams.phase, BackupPhase::COPY_STAGE);

    backupSubJob.m_SubTaskType = SUBJOB_TYPE_DATACOPY_HARDLINK_PHASE;
    m_nasHetroRestoreJob->FillBackupConfigPhase(backupParams, backupSubJob);
    EXPECT_EQ(backupParams.phase, BackupPhase::HARDLINK_STAGE);

    backupSubJob.m_SubTaskType = SUBJOB_TYPE_DATACOPY_DELETE_PHASE;
    m_nasHetroRestoreJob->FillBackupConfigPhase(backupParams, backupSubJob);
    EXPECT_EQ(backupParams.phase, BackupPhase::DELETE_STAGE);

    backupSubJob.m_SubTaskType = SUBJOB_TYPE_DATACOPY_DIRMTIME_PHASE;
    m_nasHetroRestoreJob->FillBackupConfigPhase(backupParams, backupSubJob);
    EXPECT_EQ(backupParams.phase, BackupPhase::DIR_STAGE);
}

/*
 * 用例名称：CheckScannerCtrlFileCallBack
 * 前置条件：无
 * check点：ScannerCtrlFileCallBack无异常
 */
TEST_F(HetroRestoreJobTest, CheckScannerCtrlFileCallBack)
{
    void *usrData = 0;
    string controlFilePath = "1.txt";
    EXPECT_NO_THROW(m_nasHetroRestoreJob->ScannerCtrlFileCallBack(usrData, controlFilePath));
}

/*
 * 用例名称：CheckScannerHardLinkCallBack
 * 前置条件：无
 * check点：ScannerHardLinkCallBack无异常
 */
TEST_F(HetroRestoreJobTest, CheckScannerHardLinkCallBack)
{
    void *usrData = 0;
    string controlFilePath = "1.txt";
    EXPECT_NO_THROW(m_nasHetroRestoreJob->ScannerHardLinkCallBack(usrData, controlFilePath));
}

/*
 * 用例名称：CheckRestoreDirMTimeCallBack
 * 前置条件：无
 * check点：RestoreDirMTimeCallBack无异常
 */
TEST_F(HetroRestoreJobTest, CheckRestoreDirMTimeCallBack)
{
    void *usrData = 0;
    string controlFilePath = "1.txt";
    EXPECT_NO_THROW(m_nasHetroRestoreJob->RestoreDirMTimeCallBack(usrData, controlFilePath));
}

/*
 * 用例名称：CheckRestoreDelCtrlCallBack
 * 前置条件：无
 * check点：RestoreDelCtrlCallBack无异常
 */
TEST_F(HetroRestoreJobTest, CheckRestoreDelCtrlCallBack)
{
    void *usrData = 0;
    string controlFilePath = "1.txt";
    EXPECT_NO_THROW(m_nasHetroRestoreJob->RestoreDelCtrlCallBack(usrData, controlFilePath));
}

/*
 * 用例名称：CheckCheckSmbConnectVersion
 * 前置条件：无
 * check点：CheckSmbConnectVersion流程执行成功
 */
// TEST_F(HetroRestoreJobTest, CheckCheckSmbConnectVersion)
// {
//     Stub stub;
//     stub.set(ADDR(Module::SmbContextWrapper, Init), FunctionBoolSucc);

//     std::shared_ptr<ThriftDataBase> restoreJobInfoPtr =
//         std::make_shared<AppProtect::RestoreJob>(HetroRestoreJobTest::RestoreJobInfoSetUp());
//     m_ins.m_jobCommonInfo = std::make_shared<JobCommonInfo>(restoreJobInfoPtr);
    
//     Module::SmbVersion version = Module::SmbVersion::VERSION0311;
//     int64_t errCode = HomoErrorCode::ERROR_NAS_SCAN_PROTECTED_SERVER_NOT_REACHABLE;
//     m_ins.m_jobId = "11";
//     m_ins.m_nasShare.nasShareExt.m_domainName = "1";
//     m_ins.m_nasShare.nasShareExt.m_serviceIP = "127.0.0.1";
//     m_ins.m_nasShare.sharePath = "/home/1.txt";
//     m_ins.m_nasShare.auth.authkey = "111";
//     m_ins.m_nasShare.auth.authPwd = "111";
//     m_ins.m_nasShare.auth.authType = AuthType::type::KERBEROS;
//     m_ins.m_nasShare.nasShareExt.m_encryption = SMB_ENCRYPTION;
//     m_ins.m_dataFsSvcIp = {"127.0.0.1"};
//     m_ins.m_dataFs.remotePath = "/home/1.txt";
//     m_ins.m_dataFs.auth.authkey = "111";
//     m_ins.m_dataFs.auth.authPwd = "111";
//     EXPECT_NO_THROW(m_ins.CheckSmbConnectVersion(version, errCode));
//     stub.reset(ADDR(Module::SmbContextWrapper, Init));
// }

static bool CheckRemoteNasMount_Stub_False(void *obj, std::string proto, std::string protoVersion,
        ProtectedNasShare &m_nasShare, std::string m_tempLocalMountPath)
{
    std::cout << "enter CheckRemoteNasMount_Stub_False" << std::endl;
    return false;
}

static bool PrintFinalScannerStats_Stub_True(void *obj, HetroNativeScanStatistics &scanStats)
{
    std::cout << "enter PrintFinalScannerStats_Stub_True" << std::endl;
    return true;
}

static bool PrintFinalBackupStats_Stub_True(void *obj, HetroNativeBackupStats &backupStatistics)
{
    std::cout << "enter PrintFinalBackupStats_Stub_True" << std::endl;
    return true;
}

/*
 * 用例名称：CheckCheckMountVersion
 * 前置条件：无
 * check点：CheckMountVersion运行失败
 */
// TEST_F(HetroRestoreJobTest, CheckCheckMountVersionNoCheck)
// {
//     Stub stub;
//     string proto = "1";
//     string protoVersion = "1";
//     int64_t errCode = HomoErrorCode::ERROR_NAS_SCAN_PROTECTED_SERVER_NOT_REACHABLE;
//     stub.set(ADDR(HetroCommonService, CheckRemoteNasMount), CheckRemoteNasMount_Stub_False);
//     EXPECT_EQ(m_nasHetroRestoreJob->CheckMountVersion(proto, protoVersion, errCode), MP_FALSE);
//     stub.reset(ADDR(HetroCommonService, CheckRemoteNasMount));
// }

/*
 * 用例名称：CheckPrintBackupCopyInfo
 * 前置条件：无
 * check点：PrintBackupCopyInfo运行失败
 */
TEST_F(HetroRestoreJobTest, CheckPrintBackupCopyInfo)
{
    Stub stub;
    HetroNativeBackupStats backupStatistics;

    std::shared_ptr<ThriftDataBase> restoreJobInfoPtr =
        std::make_shared<AppProtect::RestoreJob>(HetroRestoreJobTest::RestoreJobInfoSetUp());
    m_ins.m_jobCommonInfo = std::make_shared<JobCommonInfo>(restoreJobInfoPtr);

    m_ins.SetPostJobResultType(AppProtect::JobResult::type::FAILED);
    stub.set(ADDR(HetroCommonService, PrintFinalScannerStats), PrintFinalScannerStats_Stub_True);
    stub.set(ADDR(HetroCommonService, PrintFinalBackupStats), PrintFinalBackupStats_Stub_True);
    EXPECT_NO_THROW(m_ins.PrintBackupCopyInfo(backupStatistics));
    stub.reset(ADDR(HetroCommonService, PrintFinalScannerStats));
    stub.reset(ADDR(HetroCommonService, PrintFinalBackupStats));
}

/*
 * 用例名称：CheckReportScannerCompleteStatus
 * 前置条件：无
 * check点：ReportScannerCompleteStatus运行成功
 */
TEST_F(HetroRestoreJobTest, CheckReportScannerCompleteStatus)
{
    ScanStatistics scanStatistics;
    scanStatistics.mTotFailedDirs = 1;
    scanStatistics.mTotDirs = 1;
    scanStatistics.mTotFiles = 1;
    scanStatistics.mTotalSize = 1;
    scanStatistics.mTotFailedDirs = 1;
    scanStatistics.mTotDirsToBackup = 1;
    scanStatistics.mTotFilesToBackup = 1;
    scanStatistics.mTotFilesDeleted = 1;
    EXPECT_EQ(m_ins.ReportScannerCompleteStatus(scanStatistics), MP_TRUE);
}

/*
 * 用例名称：CheckReportJobProgress
 * 前置条件：无
 * check点：根据m_backupStatus不同进入不同状态的分支
 */
TEST_F(HetroRestoreJobTest, CheckReportJobProgress)
{
    std::shared_ptr<ThriftDataBase> restoreJobInfoPtr =
        std::make_shared<AppProtect::RestoreJob>(HetroRestoreJobTest::RestoreJobInfoSetUp());
    m_ins.m_jobCommonInfo = std::make_shared<JobCommonInfo>(restoreJobInfoPtr);

    std::string jobLogLabel = "nas_plugin_hetro_backup_data_fail_label";
    SubJobStatus::type jobStatus = SubJobStatus::COMPLETED;
    EXPECT_NO_THROW(m_ins.ReportJobProgress(jobStatus, jobLogLabel));

    jobStatus = SubJobStatus::RUNNING;
    m_ins.m_backupStatus = BackupPhaseStatus::FAILED_NOACCESS;
    EXPECT_NO_THROW(m_ins.ReportJobProgress(jobStatus, jobLogLabel));

    m_ins.m_backupStatus = BackupPhaseStatus::FAILED_NOSPACE;
    EXPECT_NO_THROW(m_ins.ReportJobProgress(jobStatus, jobLogLabel));

    m_ins.m_backupStatus = BackupPhaseStatus::FAILED_PROT_SERVER_NOTREACHABLE;
    EXPECT_NO_THROW(m_ins.ReportJobProgress(jobStatus, jobLogLabel));

    m_ins.m_backupStatus = BackupPhaseStatus::FAILED_SEC_SERVER_NOTREACHABLE;
    EXPECT_NO_THROW(m_ins.ReportJobProgress(jobStatus, jobLogLabel));

    m_ins.m_backupStatus = BackupPhaseStatus::FAILED;
    EXPECT_NO_THROW(m_ins.ReportJobProgress(jobStatus, jobLogLabel));
}

static int KinitTGTInner_Stub_Suc(void *obj, std::string userName, std::string password, std::string krb5Keytab,
    const std::string& krb5Conf, const std::string& uniqueFileJoinField)
{
    return MP_SUCCESS;
}

static int KinitTGTInner_Stub_Fail(void *obj, std::string userName, std::string password, std::string krb5Keytab,
    const std::string& krb5Conf, const std::string& uniqueFileJoinField)
{
    return MP_FAILED;
}

/*
 * 用例名称：CheckKinitTGT
 * 前置条件：无
 * check点：KinitTGT流程成功
 */
TEST_F(HetroRestoreJobTest, CheckKinitTGT)
{
    Stub stub;
    std::shared_ptr<ThriftDataBase> restoreJobInfoPtr =
        std::make_shared<AppProtect::RestoreJob>(HetroRestoreJobTest::RestoreJobInfoSetUp());
    m_ins.m_jobCommonInfo = std::make_shared<JobCommonInfo>(restoreJobInfoPtr);

    m_ins.m_jobCtrlPhase = JOB_CTRL_PHASE_POSTJOB;
    m_ins.m_nasShare.auth.authType = AuthType::type::APP_PASSWORD;
    m_ins.m_nasShare.nasShareExt.m_protocol = NAS_PROTOCOL_TYPE_E_NFS;
    stub.set(PluginUtils::KinitTGTInner, KinitTGTInner_Stub_Suc);
    EXPECT_EQ(m_ins.KinitTGT(), MP_TRUE);
    stub.reset(PluginUtils::KinitTGTInner);
}

/*
 * 用例名称：CheckKinitTGT
 * 前置条件：无
 * check点：KinitTGT流程失败
 */
// TEST_F(HetroRestoreJobTest, CheckKinitTGTNoKinit)
// {
//     Stub stub;
//     std::shared_ptr<ThriftDataBase> restoreJobInfoPtr =
//         std::make_shared<AppProtect::RestoreJob>(HetroRestoreJobTest::RestoreJobInfoSetUp());
//     m_ins.m_jobCommonInfo = std::make_shared<JobCommonInfo>(restoreJobInfoPtr);
//     AppProtect::RestoreJob restoreJob = HetroRestoreJobTest::RestoreJobInfoSetUp();
//     // m_ins.m_restoreJobPtr = std::shared_ptr<AppProtect::RestoreJob>(restoreJob);
//     m_ins.m_restoreJobPtr->targetObject.auth.extendInfo = "{\"copyId\":\"precopyId\", \"isCurrentCopyRepo\": false, \"timestamp\": 1644374672}";
//     m_ins.m_jobCtrlPhase = JOB_CTRL_PHASE_PREJOB;
//     m_ins.m_nasShare.auth.authType = AuthType::type::KERBEROS;
//     m_ins.m_nasShare.nasShareExt.m_protocol = NAS_PROTOCOL_TYPE_E_CIFS;
//     stub.set(PluginUtils::KinitTGTInner, KinitTGTInner_Stub_Fail);
//     EXPECT_EQ(m_ins.KinitTGT(), MP_FALSE);
//     stub.reset(PluginUtils::KinitTGTInner);
// }

/*
 * 用例名称：ResolveSharePathForCIFSTest
 * 前置条件：无
 * check点：cifs sharepath成功分解为sharename和rootPath
 */
TEST_F(HetroRestoreJobTest, ResolveSharePathForCIFSTest)
{
    Stub stub;
    std::shared_ptr<ThriftDataBase> restoreJobInfoPtr =
        std::make_shared<AppProtect::RestoreJob>(HetroRestoreJobTest::RestoreJobInfoSetUp());
    std::pair<std::string, std::string> p1("share1145141919810", "");
    EXPECT_EQ(m_ins.ResolveSharePathForCIFS("/share1145141919810"), p1);

    std::pair<std::string, std::string> p2("share1145141919810", "dir1/dir2");
    EXPECT_EQ(m_ins.ResolveSharePathForCIFS("/share1145141919810/dir1/dir2/"), p2);

    std::pair<std::string, std::string> p3("share1145141919810", "dir1");
    EXPECT_EQ(m_ins.ResolveSharePathForCIFS("/share1145141919810/dir1"), p3);
}